/*
	Todo: Need to optimize the rebuild part
	
	Class: iTable
		A table is loaded via ajax and is made sortable
	
	Usage:
		Works with any table
	
	Parameters:
		container - Id of the table container.
		minCols - Minimum number of cols for a row (else we skip this row)
		atFirstSortBy - By default, sort by this col
		ascClass - Helper class for <th/> (can help the creation of arrows or something like this)
		dscClass - Helper class for <th/>
		selectedClass - Class for the selected row
		oddClass - Odd class to create stripes
		evenClass - Even class to creaste stripes
		
	Example:
		In the <head> of the html file
			(code)
			<link media="screen" rel="stylesheet" href="css/itable.css" type="text/css"/>
			<script src="js/mootools.js" type="text/javascript"></script>
			<script src="js/itable.js" type="text/javascript"></script>
			(end code)
		1: Simply make a sortable table (which is in 'idOfTheContainer')
			(code)
			<script type="text/javascript">
			window.addEvent("domready", function() {
				new iTable('idOfTheContainer', {tableClass:'border'});
			});
			</script>
			(end code)
		2: If you wish to get the table via ajax
			(code)
			<script type="text/javascript">
			window.addEvent("domready", function() {
				var myAjax = new Ajax('url/of/the.table', {
					method: 'get',
					onComplete : function(){new iTable('idOfTheContainer')}.bind(this),
					update: 'idOfTheContainer'
				}).request();	
			});
			</script>
			(end code)
			
			
	Require:
		(code)
		Core
		
		    * Core.js
		
		Class
		
		    * Class.js
		    * Class.Extras.js
		
		Native
		
		    * Array.js
		    * String.js
		    * Function.js
		    * Number.js
		    * Element.js
		
		Element
		
		    * Element.Filters.js
		    * Element.Selectors.js
		    * Element.Form.js
		
		Remote
		
		    * XHR.js
		    * Ajax.js
		(end code)			

	About:
		formcheck.js v.1.0 for mootools v1.1 05 / 2007
		
		by Floor SA (http://www.floor.ch) MIT-style license
		
		Created by Luca Pillonel and David Mignot, last modified by Luca Pillonel 30.05.12
		
	Todo:
		Class simplify on th -> simplify this cols. Possibility to do others usefull things (class="currency chf" 3.03 -> 3.50 chf)
		
*/

var iTable = new Class({
	options: {
		minCols			: 0,
		atFirstSortBy		: 0,
		tableClass		: 'itable',
		roundNumber		: 2,
		ascClass		: 'asc',
		dscClass		: 'dsc',
		selectedClass		: 'selected',
		oddClass		: 'odd',
		evenClass		: 'even',
		simplifyNumbers		: 1
	},
	
	/*
	Constructor: initialize
		Constructor
		
		Set the options and start the ajaxRequest
	*/
	
	initialize: function(container, options) {
		this.firstPass = 0;
		this.setOptions(options);
		(function(){this.readTable(container);}.bind(this)).delay(7);
		
	},
	
	/*
	Method: tablePrep
		Internal method
		
		Prepare the table

	Parameters:
		co - ID of the result container
	*/
	
	readTable: function(co){
		// Prepare the titles
		this.container = co;
		this.titles = [];
		$ES('th', co).each(function(el, n){ 
			this.titles[n] = el.innerHTML;
			el.addEvent('click', function(){this.sortBy(n);}.bind(this));
		}.bind(this));
		
		// Create an array from the table
		this.cache = [];
		$ES('tr', $E('table', co)).each(function(el, n){
			if(n>0){
				if(n % 2 == 0)el.addClass('stripes'); 
				var td = $ES('td', $(el));
				if(td.length > this.options.minCols){
					// For each column
					this.cache[n-1] = new Array();
					td.each(function(le, o){
						var inTxt = le.innerHTML;
						if(this.options.simplifyNumbers == 1 && !isNaN(inTxt)){inTxt = this.symplify(inTxt)}
						this.cache[n-1].push(inTxt);
					}.bind(this));
				}
			}
		}.bind(this));
		this.sortBy(this.options.atFirstSortBy);
	},
	
	/*
	Method: constructTable
		Internal method
		
		Create a new table from the original one
	*/
	
	rebuild: function(){
		var co = this.container;
		var object = this.cache;
		var titles = this.titles;
		
		// If exist, remove the old results
		if(this.mtbody){
			this.mtbody.remove();
		}
		
		// Create the table if it has not been already done
		if(!this.mtable){
			this.mtable = new Element('table').addClass('resultTable').injectInside(co);
			this.mtable.addClass( this.options.tableClass );
			this.mthead = new Element('thead').injectInside(this.mtable);
			this.mtht = new Element('tr').injectInside(this.mthead);
			
			// Makes the titles clickable
			$ES('th', co).each(function(el, n){
				var tmp = new Element('th');
				this.mtht.adopt(tmp.setHTML(titles[n]).addEvent('click', function(){this.sortBy(n);}.bind(this)));
				if(this.options.atFirstSortBy == n){tmp.addClass(this.options.ascClass);tmp.addClass(this.options.selectedClass);}
			}.bind(this));
		}
		
		// remove the first table
		if($('otable')){$('otable').remove();}
		
		// Create the results part
		this.mtbody = new Element('tbody').injectInside(this.mtable);
		object.each(function(el, n){
			var mtr = new Element('tr').injectInside(this.mtbody);
			// add the stripe
			if (n % 2 == 0){
				mtr.addClass(this.options.oddClass);
			} else {
				mtr.addClass(this.options.evenClass);
			}
			// create the cells
			el.each(function(le, o){
				if(o == 4 && !isNaN(el[o])){this.symplify(el[o])}
				mtr.adopt(new Element('td').setHTML(el[o]));
			}.bind(this));
		}.bind(this));
	},
	
	/*
	Method: sortBy
		Internal method
		
	Parameters:
		n - Column number
	*/
	
	sortBy: function(n){
		var co = this.container;
		var titles = this.titles;
		// First clean the titles class
		var t = $ES('th', co);
		t.each(function(el, i){
			if(n != i){
				el.removeClass(this.options.ascClass);
				el.removeClass(this.options.dscClass);
				el.removeClass(this.options.selectedClass);
			}
		}.bind(this));
		// Then add the helpers class
		t[n].addClass(this.options.selectedClass);
		if(t[n].hasClass(this.options.ascClass)){
			t[n].addClass(this.options.dscClass);
			t[n].removeClass(this.options.ascClass);
		} else{
			t[n].addClass(this.options.ascClass);
			t[n].removeClass(this.options.dscClass)
		}
		
		// Compare the elements
		this.sortby = n;
		this.cache = this.cache.sort(this.comPare.bind(this));
		this.rebuild();
	},
	
	/*
	Method: comPare
		Internal method
		
	Parameters:
		a, b - The element to compare (passed by default on a "array.sort()"
	*/
	
	comPare: function(a, b)
	{
		var co = this.container;
		var n = this.sortby;
		if(a[n]){
			var th = $ES('th', co);
			
			// If String
			if(isNaN(a[n])){
				a[n].toLowerCase(); a[n].trim();
				b[n].toLowerCase(); b[n].trim();
				if(th[n].hasClass(this.options.ascClass)){
					return (b[n] < a[n]) - (a[n] < b[n]);
				} else{
					return (a[n] < b[n]) - (b[n] < a[n]);
				}
			
			// If Number
			} else {
				if(th[n].hasClass(this.options.ascClass)){
					return(b[n]-a[n]);
				} else{
					return(a[n]-b[n]);
				}
			}
		}
	},
	
	/*
	Method: simplify
		Internal method

	Parameters:
		number - A number to simplify. ex: 12.38442 -> 12.38
	*/
	
	symplify: function(number)
	{
		var number =  eval(number).round(this.options.roundNumber);
		ans = number * 1000;
		ans = Math.round(ans /10) + "";
		return ans.substring(0,ans.length-2) + "." + ans.substring(ans.length-2,ans.length);
	}
});

iTable.implement(new Options);// Implements setOptions(defaults, options)